/*
* This file is a part of the open-eBackup project.
* This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0.
* If a copy of the MPL was not distributed with this file, You can obtain one at
* http://mozilla.org/MPL/2.0/.
*
* Copyright (c) [2024] Huawei Technologies Co.,Ltd.
*
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
*/
#include <iostream>
#include "gtest/gtest.h"
#include "gmock/gmock.h"
#include "named_stub.h"
#include "mockcpp/mockcpp.hpp"
#include "ApplicationProtectPlugin_types.h"
#include "ApplicationProtectBaseDataType_types.h"
#include "backup/ReplicationBackupJob.h"
#include "ReplicationRestoreJob.h"
#include "ReplicationCommonService.h"
#include "ClientInvoke.h"
#include "PluginUtilities.h"
#include "device_access/ControlDevice.h"
#include "utils/CertMgr.h"
#include "nas_share/common/HetroCommonService.h"

using ::testing::_;
using testing::AllOf;
using ::testing::AnyNumber;
using ::testing::AtLeast;
using testing::ByMove;
using testing::DoAll;
using ::testing::Eq;
using ::testing::Field;
using ::testing::Ge;
using ::testing::Gt;
using testing::InitGoogleMock;
using ::testing::Invoke;
using ::testing::Ne;
using ::testing::Return;
using ::testing::Sequence;
using ::testing::SetArgReferee;
using ::testing::SetArgumentPointee;
using ::testing::Throw;
using namespace NasRepServiceObjOp;
using namespace AppProtect;
using namespace std;
using namespace Module;

class ReplicationCommonServiceTest : public testing::Test {
public:
    void SetUp();
    void TearDown();
    static void SetUpTestCase() {}
    static void TearDownTestCase() {}
    LLTSTUB::Stub stub;
    std::string m_pairID;
    std::shared_ptr<DoradoNas> m_localController;
    std::shared_ptr<DoradoNas> m_remoteController;
    std::unique_ptr<ReplicationBackupJob> m_nasReplicationCommonService;
};

static AppProtect::BackupJob BackupJobSetup()
{
    BackupJob homoBackupJob;
    
    homoBackupJob.jobId = "main_job_id_000";
    homoBackupJob.requestId = "000001";
    homoBackupJob.protectEnv.__isset.auth = true;
    homoBackupJob.protectEnv.auth.__set_authkey("admin");
    homoBackupJob.protectEnv.auth.__set_authPwd("Admin@123");
    homoBackupJob.protectEnv.__set_endpoint("8.40.102.115");
    homoBackupJob.protectEnv.__set_port(8088);
    homoBackupJob.protectEnv.extendInfo = "{\"snapConsistency\":\"0\",\"verifyStatus\":\"1\",\"wwn\":\"\"}";
    homoBackupJob.protectEnv.auth.extendInfo = "{\"fingerPrint\" : \"4928EBB6E58A3A395BC89317DD55B82F1B8C10E7\"}";

    homoBackupJob.protectObject.__set_id("147");
    homoBackupJob.protectObject.__set_name("test_123456");
    homoBackupJob.protectObject.__set_extendInfo("{\"tenantName\":\"d0\", \"fileSystemId\":\"148\", \"usedCapacity\":\"5986\", \"onlineStatus\":\"1\", \"tenantId\":\"15\", \"capacity\":\"123456789\"}");
    
    StorageRepository storage;
    storage.__isset.auth = true;
    storage.__isset.endpoint = true;

    storage.repositoryType = RepositoryDataType::type::DATA_REPOSITORY;
    storage.auth.__set_authkey("admin");
    storage.auth.__set_authPwd("Admin@123");
    storage.endpoint.ip = "8.40.102.105,8.40.102.106";
    storage.endpoint.port = 8088;
    storage.__set_remotePath("/Storage_1234/123456789");

    StorageRepository storage2;
    storage2.__isset.auth = true;
    storage2.__isset.endpoint = true;

    storage2.repositoryType = RepositoryDataType::type::META_REPOSITORY;
    storage2.auth.__set_authkey("admin");
    storage2.auth.__set_authPwd("Admin@123");
    storage2.endpoint.ip = "8.40.102.105,8.40.102.106";
    storage2.endpoint.port = 8088;
    storage2.__set_remotePath("/Storage_1234/123456789");
    vector<string> path {"/home"};
    storage2.__set_path(path);

    // Copy copy1 {};
    // vector<StorageRepository> repos1 {};
    // repos1.push_back(storage);
    // repos1.push_back(storage2);
    // copy1.__set_repositories(repos1);
    // vector<Copy> copies {};
    // copies.push_back(copy1);

    // homoBackupJob.__set_copy(copies);
    homoBackupJob.repositories.push_back(storage);
    homoBackupJob.repositories.push_back(storage2);

    return homoBackupJob;
}

// static bool QueryFileSystem_Stub_Suc(void *obj, DeviceDetails &info)
// {
//     return SUCCESS;
// }

void ReplicationCommonServiceTest::SetUp()
{
    m_nasReplicationCommonService = std::make_unique<ReplicationBackupJob>();
    SubJob subJob;
    // subJobId keyword is optional, this operation is necessary
    subJob.__isset.subJobId = true;
    subJob.__set_jobId("sub_job_id");
    subJob.jobId = "jobId123";
    subJob.subJobId = "subJob123";
    subJob.jobName = "XYZ";
    subJob.jobPriority = 1;
    subJob.jobInfo = "{\"ControlFile\":\"\",\"SubTaskType\":1,\"Ext\":\"\"}";

    // // test BackupPrerequisiteJob
    // CommonServiceJob ServiceJob = ReplicationCommonServiceSetup();
    // auto jobInfo = make_shared<JobCommonInfo>(make_shared<CommonServiceJob>(ServiceJob));
    // m_nasReplicationCommonService->SetJobInfo(jobInfo);
    // m_nasReplicationCommonService->m_backupPara = make_shared<CommonServiceJob>(ServiceJob);
    std::shared_ptr<SubJob> subJobptr = std::make_shared<SubJob>(subJob);
    m_nasReplicationCommonService->SetSubJob(subJobptr);

    ControlDeviceInfo basicDeviceInfo;
    basicDeviceInfo.deviceName = "test";  // 文件系统名称在pair预处理过程中或者新创pair时会设置，此处不需要
    basicDeviceInfo.url = "";   // 使用安全IP登录，不需要IP和端口号
    basicDeviceInfo.port = "";  // 使用安全IP登录，不需要IP和端口号
    basicDeviceInfo.userName = "admin";
    basicDeviceInfo.password = "Huawei@123";
    basicDeviceInfo.poolId = 0;
    basicDeviceInfo.compress = false;
    basicDeviceInfo.dedup = false;
    basicDeviceInfo.poolId = 0;
    std::string m_productFSID = "1";
    m_localController = std::make_unique<DoradoNas>(basicDeviceInfo, false);
    m_remoteController = std::make_unique<DoradoNas>(basicDeviceInfo, false);
    m_nasReplicationCommonService->m_remoteDeviceController = std::make_unique<DoradoNas>(basicDeviceInfo, m_productFSID, false);
}

void ReplicationCommonServiceTest::TearDown()
{
    // stub.reset(ADDR(BasicJob, GetJobInfo));
    // stub.reset(ADDR(DoradoNas, QueryFileSystem));
    // Stub stub;
    // stub.reset(sleep);
}

static void CheckCertThumbPrint_Stub_SUC(void *obj, ActionResult& returnValue, const std::string& ip, const int32_t port, const std::string& thumbPrint)
{
    returnValue.code = MP_SUCCESS;
    return;
}

static bool CheckDeviceNetworkConnect_Stub_True()
{
    std::cout << "CheckDeviceNetworkConnect_Stub_True get called!";
    return true;
}

static bool UpdateDeviceAvilableIP_Stub_True(void *obj, ControlDeviceInfo &deviceInfo,
    const std::vector<std::string> &mgrIpList)
{
    return true;
}

static bool InitializeTask_Stub_True(void *obj)
{
    return true;
}

static bool InitializeTask_Stub_False(void *obj)
{
    return false;
}

static bool AfterInitializeTask_Stub_True(void *obj)
{
    return true;
}

static bool AfterInitializeTask_Stub_False(void *obj)
{
    return false;
}

static bool StartTask_Stub_True(void *obj, std::shared_ptr<DoradoNas>& localController)
{
    return true;
}

static bool StartTask_Stub_False(void *obj, std::shared_ptr<DoradoNas>& localController)
{
    return false;
}

static bool StartMonitorTask_Stub_True(void *obj, std::shared_ptr<DoradoNas>& localController,
    std::shared_ptr<DoradoNas>& remoteController)
{
    return true;
}

static bool StartMonitorTask_Stub_False(void *obj, std::shared_ptr<DoradoNas>& localController,
    std::shared_ptr<DoradoNas>& remoteController)
{
    return false;
}

static bool IsAbortJob_Stub_True(void *obj)
{
    return true;
}

static bool IsAbortJob_Stub_False(void *obj)
{
    return false;
}

static bool InitDeviceInfo_Stub_True(void *obj)
{
    return true;
}

static bool GetPairInfoByID_Stub_True(void *obj, std::shared_ptr<DoradoNas>& deviceController, const std::string& pairID,
    ReplicationPairInfo& replicationPairInfo)
{
    return true;
}

static bool GetPairInfoByID_Stub_False(void *obj, std::shared_ptr<DoradoNas>& deviceController, const std::string& pairID,
    ReplicationPairInfo& replicationPairInfo)
{
    return false;
}

static bool ActiveReplicationPair_Stub_True(void *obj, std::shared_ptr<DoradoNas>& localController)
{
    return true;
}

static bool ActiveReplicationPair_Stub_False(void *obj, std::shared_ptr<DoradoNas>& localController)
{
    return false;
}

static bool SplitReplicationPair_Stub_True(void *obj, std::shared_ptr<DoradoNas>& deviceController,
    const std::string& pairID)
{
    return true;
}

static bool SplitReplicationPair_Stub_False(void *obj, std::shared_ptr<DoradoNas>& deviceController,
    const std::string& pairID)
{
    return false;
}

static bool SwitchOverPrimaryAndSecondResource_Stub_True(void *obj, std::shared_ptr<DoradoNas>& deviceController,
    const std::string& pairID)
{
    return true;
}

static bool SwitchOverPrimaryAndSecondResource_Stub_False(void *obj, std::shared_ptr<DoradoNas>& deviceController,
    const std::string& pairID)
{
    return false;
}

static bool SecondaryResourceProtectEnable_Stub_True(void *obj, std::shared_ptr<DoradoNas>& deviceController,
    const std::string& pairID)
{
    return true;
}

static bool SecondaryResourceProtectEnable_Stub_False(void *obj, std::shared_ptr<DoradoNas>& deviceController,
    const std::string& pairID)
{
    return false;
}

static bool SecondaryResourceProtectDisable_Stub_True(void *obj, std::shared_ptr<DoradoNas>& deviceController,
    const std::string& pairID)
{
    return true;
}

static bool SecondaryResourceProtectDisable_Stub_False(void *obj, std::shared_ptr<DoradoNas>& deviceController,
    const std::string& pairID)
{
    return false;
}


static bool InitInfo_Stub_True(void *obj, const AppProtect::ApplicationEnvironment& protectEnv)
{
    return true;
}

static bool InitInfo_Stub_False(void *obj, const AppProtect::ApplicationEnvironment& protectEnv)
{
    return false;
}

static bool IsVerify_Stub_True(void *obj)
{
    return true;
}

static bool IsVerify_Stub_False(void *obj)
{
    return false;
}

static bool FlushCertificationToDisk_Stub_True(void *obj)
{
    return true;
}

static bool FlushCertificationToDisk_Stub_False(void *obj)
{
    return false;
}

static string GetCertPath_Stub(void *obj)
{
    return "/1.txt";
}

static bool IncludeRevocationList_Stub_True(void *obj)
{
    return true;
}

static bool IncludeRevocationList_Stub_False(void *obj)
{
    return false;
}

static bool FlushRevocationListToDisk_Stub_True(void *obj)
{
    return true;
}

static bool FlushRevocationListToDisk_Stub_False(void *obj)
{
    return false;
}

static string GetCrlPath_Stub(void *obj)
{
    return "/1.txt";
}

static bool RemoveCertAndRevocationListFromDisk_Stub_True(void *obj)
{
    return true;
}

static bool RemoveCertAndRevocationListFromDisk_Stub_False(void *obj)
{
    return false;
}

static bool PreStartTask_Stub_True(void *obj)
{
    return true;
}

static bool PreStartTask_Stub_False(void *obj)
{
    return false;
}

static bool OpenPerformanceStatisticSwitch_Stub_True(void *obj, std::shared_ptr<DoradoNas>& deviceController)
{
    return true;
}

static bool OpenPerformanceStatisticSwitch_Stub_False(void *obj, std::shared_ptr<DoradoNas>& deviceController)
{
    return false;
}

static int QueryFileSystem_Stub_True(void *obj, std::string fileName, DeviceDetails &info)
{
    info.usedCapacity = 2;
    return 0;
}

static int QueryFileSystem_Stub_False(void *obj, std::string fileName, DeviceDetails &info)
{
    return 0;
}

static int MonitorTask_Stub_Suc(void *obj, std::shared_ptr<DoradoNas>& localController,
    std::shared_ptr<DoradoNas>& remoteController)
{
    return MP_SUCCESS;
}

static int MonitorTask_Stub_Fail(void *obj, std::shared_ptr<DoradoNas>& localController,
    std::shared_ptr<DoradoNas>& remoteController)
{
    return MP_FAILED;
}

static bool IsReportAgentErrorCode_Stub_True(void *obj, LogDetail logDetail)
{
    return true;
}

static bool IsReportAgentErrorCode_Stub_False(void *obj, LogDetail logDetail)
{
    return false;
}

TEST_F(ReplicationCommonServiceTest, CheckAllowBackupInLocalNode)
{
    EXPECT_NO_THROW(m_nasReplicationCommonService->AllowBackupInLocalNode());
}

TEST_F(ReplicationCommonServiceTest, CheckCheckBackupJobType)
{
    EXPECT_EQ(m_nasReplicationCommonService->CheckBackupJobType(), MP_SUCCESS);
}

/*
 * 用例名称:检查前置任务流程
 * 前置条件：无
 * check点：检查前置任务流程顺利运行
 */
TEST_F(ReplicationCommonServiceTest, CheckPrerequisiteJob)
{
    typedef bool (*fptr)(ReplicationBackupJob*);
    fptr ReplicationBackupJob_InitializeTask = (fptr)(&ReplicationBackupJob::InitializeTask);

    stub.set(ReplicationBackupJob_InitializeTask, InitializeTask_Stub_True);
    stub.set(ADDR(ReplicationCommonService, AfterInitializeTask), AfterInitializeTask_Stub_True);
    EXPECT_EQ(m_nasReplicationCommonService->PrerequisiteJob(), MP_SUCCESS);
    stub.reset(ReplicationBackupJob_InitializeTask);
    stub.reset(ADDR(ReplicationCommonService, AfterInitializeTask));
}

/*
 * 用例名称:检查前置任务流程
 * 前置条件：无
 * check点：检查前置任务流程缺乏Initialize失败
 */
TEST_F(ReplicationCommonServiceTest, CheckPrerequisiteJobInitializeFailed)
{
    typedef bool (*fptr)(ReplicationBackupJob*);
    fptr ReplicationBackupJob_InitializeTask = (fptr)(&ReplicationBackupJob::InitializeTask);

    stub.set(ReplicationBackupJob_InitializeTask, InitializeTask_Stub_False);
    stub.set(ADDR(ReplicationCommonService, AfterInitializeTask), AfterInitializeTask_Stub_True);
    EXPECT_EQ(m_nasReplicationCommonService->PrerequisiteJob(), MP_FAILED);
    stub.reset(ReplicationBackupJob_InitializeTask);
    stub.reset(ADDR(ReplicationCommonService, AfterInitializeTask));
}

/*
 * 用例名称:检查前置任务流程
 * 前置条件：无
 * check点：检查前置任务流程缺乏AfterInitialize失败
 */
TEST_F(ReplicationCommonServiceTest, CheckPrerequisiteJobAfterInitializeFailed)
{
    typedef bool (*fptr)(ReplicationBackupJob*);
    fptr ReplicationBackupJob_InitializeTask = (fptr)(&ReplicationBackupJob::InitializeTask);

    stub.set(ReplicationBackupJob_InitializeTask, InitializeTask_Stub_True);
    stub.set(ADDR(ReplicationCommonService, AfterInitializeTask), AfterInitializeTask_Stub_False);
    EXPECT_EQ(m_nasReplicationCommonService->PrerequisiteJob(), MP_FAILED);
    stub.reset(ReplicationBackupJob_InitializeTask);
    stub.reset(ADDR(ReplicationCommonService, AfterInitializeTask));
}

static bool LoadClientCertificate_Stub_True(void *obj)
{
    return true;
}

/*
 * 用例名称: 检查生成子任务流程
 * 前置条件：无
 * check点：检查生成子任务流程失败
 */
 static void Void_stub() {
     std::cout << "Stub sleep" << std::endl;
    return;
}
TEST_F(ReplicationCommonServiceTest, CheckGenerateSubJob)
{
    // stub.set(ADDR(SslSocketPasswordFactory, LoadClientCertificate), LoadClientCertificate_Stub_True);
    // Stub stub;
    stub.set(sleep, Void_stub);
    EXPECT_EQ(m_nasReplicationCommonService->GenerateSubJob(), MP_FAILED);
    stub.reset(sleep);
    // stub.reset(ADDR(SslSocketPasswordFactory, LoadClientCertificate));
}

/*
 * 用例名称: 检查执行子任务流程
 * 前置条件：无
 * check点：检查执行子任务流程顺利运行
 */
TEST_F(ReplicationCommonServiceTest, CheckExecuteSubJob)
{
    stub.set(ADDR(ReplicationCommonService, StartTask), StartTask_Stub_True);
    stub.set(ADDR(ReplicationCommonService, StartMonitorTask), StartMonitorTask_Stub_True);
    stub.set(ADDR(BasicJob, IsAbortJob), IsAbortJob_Stub_False);
    EXPECT_EQ(m_nasReplicationCommonService->ExecuteSubJob(), MP_SUCCESS);
    stub.reset(ADDR(ReplicationCommonService, StartTask));
    stub.reset(ADDR(ReplicationCommonService, StartMonitorTask));
    stub.reset(ADDR(BasicJob, IsAbortJob));
}

/*
 * 用例名称: 检查执行子任务流程
 * 前置条件：无
 * check点：检查执行子任务流程失败
 */
TEST_F(ReplicationCommonServiceTest, CheckExecuteSubJobNoStartTask)
{
    stub.set(ADDR(ReplicationCommonService, StartTask), StartTask_Stub_False);
    EXPECT_EQ(m_nasReplicationCommonService->ExecuteSubJob(), MP_FAILED);
    stub.reset(ADDR(ReplicationCommonService, StartTask));
}

/*
 * 用例名称: 检查执行子任务流程
 * 前置条件：无
 * check点：检查执行子任务流程失败
 */
TEST_F(ReplicationCommonServiceTest, CheckExecuteSubJobNoStartMonitorTask)
{
    stub.set(ADDR(ReplicationCommonService, StartTask), StartTask_Stub_True);
    stub.set(ADDR(ReplicationCommonService, StartMonitorTask), StartMonitorTask_Stub_False);
    EXPECT_EQ(m_nasReplicationCommonService->ExecuteSubJob(), MP_FAILED);
    stub.reset(ADDR(ReplicationCommonService, StartTask));
    stub.reset(ADDR(ReplicationCommonService, StartMonitorTask));
}

/*
 * 用例名称: 检查执行子任务流程
 * 前置条件：无
 * check点：检查执行子任务流程顺利运行
 */
TEST_F(ReplicationCommonServiceTest, CheckExecuteSubJobAbortJob)
{
    stub.set(ADDR(ReplicationCommonService, StartTask), StartTask_Stub_True);
    stub.set(ADDR(ReplicationCommonService, StartMonitorTask), StartMonitorTask_Stub_True);
    stub.set(ADDR(BasicJob, IsAbortJob), IsAbortJob_Stub_True);
    EXPECT_EQ(m_nasReplicationCommonService->ExecuteSubJob(), MP_FAILED);
    stub.reset(ADDR(ReplicationCommonService, StartTask));
    stub.reset(ADDR(ReplicationCommonService, StartMonitorTask));
    stub.reset(ADDR(BasicJob, IsAbortJob));
}


static bool DeleteResourceMock()
{
    return true;
}

/*
 * 用例名称: 检查后置子任务流程
 * 前置条件：无
 * check点：检查执行后置任务流程顺利运行
 */
TEST_F(ReplicationCommonServiceTest, CheckPostJob)
{
    AppProtect::BackupJob backupJob = BackupJobSetup();
    std::shared_ptr<JobCommonInfo> jobInfo = make_shared<JobCommonInfo>(make_shared<BackupJob>(backupJob));
    m_nasReplicationCommonService->m_jobCommonInfo = jobInfo;

    stub.set((int(DoradoNas::*)(std::string, DeviceDetails&))ADDR(DoradoNas, QueryFileSystem), QueryFileSystem_Stub_True);
    stub.set(ADDR(SecurityService, CheckCertThumbPrint), CheckCertThumbPrint_Stub_SUC);
    stub.set(ADDR(PluginUtils,CheckDeviceNetworkConnect), CheckDeviceNetworkConnect_Stub_True);
    stub.set(ADDR(ReplicationCommonService, UpdateDeviceAvilableIP), UpdateDeviceAvilableIP_Stub_True);
    stub.set(ADDR(HetroCommonService, DeleteResource), DeleteResourceMock);
    EXPECT_NO_THROW(m_nasReplicationCommonService->PostJob());
    stub.reset(ADDR(HetroCommonService, DeleteResource));
    stub.reset((int(DoradoNas::*)(std::string, DeviceDetails&))ADDR(DoradoNas, QueryFileSystem));
    stub.reset(ADDR(SecurityService, CheckCertThumbPrint));
    stub.reset(ADDR(ReplicationCommonService, UpdateDeviceAvilableIP));
    stub.reset(ADDR(PluginUtils, CheckDeviceNetworkConnect));
}

// ip从左到右先后为：本地存在且能获取esn的ip，本地存在但是获取不到esn的ip，本地不存在且取不到esn的ip
static std::vector<std::string> mgrIpList = {"127.0.0.1", "0.0.0.0", "192.168.1.1"};
static int GetESNInvoke(DoradoNas* ptr, string& esn)
{
    if (ptr->DoradoIP == mgrIpList.front()) {
        esn = string("0000");
        return MP_SUCCESS;
    } else {
        return MP_FAILED;
    }
}

/*
 * 用例名称: CheckUpdateDeviceAvilableIP
 * 前置条件：无
 * check点：检查UpdateDeviceAvilableIP流程顺利运行
 */
TEST_F(ReplicationCommonServiceTest, CheckUpdateDeviceAvilableIP)
{
    MOCKER_CPP(&DoradoNas::GetESN)
        .stubs()
        .will(invoke(GetESNInvoke));

    ControlDeviceInfo deviceInfo;
    // 本地设备中包含一个有效ip，一个无效ip
    for (std::size_t i = 0; i < mgrIpList.size()-1; ++i) {
        std::shared_ptr<DoradoNas> deviceControl = std::make_shared<DoradoNas>(deviceInfo, false);
        nasreplicationservice::ReplicationDeviceManager::GetInstance().AddDevice(mgrIpList[i], deviceControl);
    }
    
    EXPECT_EQ(m_nasReplicationCommonService->UpdateDeviceAvilableIP(deviceInfo, mgrIpList), true);
    // 正确反向遍历ip列表后，无效ip会被删除，直到遇到第一个有效ip，在此用例中有效ip数量为1
    EXPECT_EQ(nasreplicationservice::ReplicationDeviceManager::GetInstance().m_deviceMap.size(), 1);
}

/*
 * 用例名称: CheckStartMonitorTask
 * 前置条件：无
 * check点：检查StartMonitorTask流程顺利运行
 */
TEST_F(ReplicationCommonServiceTest, CheckStartMonitorTask)
{
    stub.set(ADDR(ReplicationCommonService, MonitorTask), MonitorTask_Stub_Suc);
    stub.set(ADDR(ReplicationCommonService, IsReportAgentErrorCode), IsReportAgentErrorCode_Stub_False);
    EXPECT_EQ(m_nasReplicationCommonService->StartMonitorTask(m_localController, m_remoteController), MP_TRUE);
    stub.reset(ADDR(ReplicationCommonService, MonitorTask));
    stub.reset(ADDR(ReplicationCommonService, IsReportAgentErrorCode));
}

/*
 * 用例名称: CheckStartMonitorTaskIsReport
 * 前置条件：无
 * check点：检查StartMonitorTask流程失败
 */
TEST_F(ReplicationCommonServiceTest, CheckStartMonitorTaskIsReport)
{
    stub.set(ADDR(NasReplicationService, GetPairInfoByID), GetPairInfoByID_Stub_True);
    stub.set(ADDR(PluginUtils,CheckDeviceNetworkConnect), CheckDeviceNetworkConnect_Stub_True);
    EXPECT_EQ(m_nasReplicationCommonService->StartMonitorTask(m_localController, m_remoteController), MP_FALSE);
    stub.reset(ADDR(NasReplicationService, GetPairInfoByID));
    stub.reset(ADDR(PluginUtils, CheckDeviceNetworkConnect));
}

/*
 * 用例名称: CheckStartMonitorTaskIsBackUpFlow
 * 前置条件：无
 * check点：检查StartMonitorTask流程失败
 */
TEST_F(ReplicationCommonServiceTest, CheckStartMonitorTaskIsBackUpFlow)
{   
    m_nasReplicationCommonService->m_isBackUpFlow = true;
    stub.set(ADDR(ReplicationCommonService, MonitorTask), MonitorTask_Stub_Fail);
    stub.set(ADDR(ReplicationCommonService, IsReportAgentErrorCode), IsReportAgentErrorCode_Stub_False);
    EXPECT_EQ(m_nasReplicationCommonService->StartMonitorTask(m_localController, m_remoteController), MP_FALSE);
    stub.reset(ADDR(ReplicationCommonService, MonitorTask));
    stub.reset(ADDR(ReplicationCommonService, IsReportAgentErrorCode));
}

/*
 * 用例名称: CheckStartMonitorTaskNoBackUpFlow
 * 前置条件：无
 * check点：检查StartMonitorTask流程失败
 */
TEST_F(ReplicationCommonServiceTest, CheckStartMonitorTaskNoBackUpFlow)
{   
    m_nasReplicationCommonService->m_isBackUpFlow = false;
    stub.set(ADDR(ReplicationCommonService, MonitorTask), MonitorTask_Stub_Fail);
    stub.set(ADDR(ReplicationCommonService, IsReportAgentErrorCode), IsReportAgentErrorCode_Stub_False);
    EXPECT_EQ(m_nasReplicationCommonService->StartMonitorTask(m_localController, m_remoteController), MP_FALSE);
    stub.reset(ADDR(ReplicationCommonService, MonitorTask));
    stub.reset(ADDR(ReplicationCommonService, IsReportAgentErrorCode));
}

/*
 * 用例名称: CheckActiveReplicationPair
 * 前置条件：无
 * check点：检查ActiveReplicationPair流程顺利运行
 */
TEST_F(ReplicationCommonServiceTest, CheckActiveReplicationPair)
{
    stub.set(ADDR(NasReplicationService, ActiveReplicationPair), ActiveReplicationPair_Stub_True);
    EXPECT_EQ(m_nasReplicationCommonService->ActiveReplicationPair(m_localController), MP_TRUE);
    stub.reset(ADDR(NasReplicationService, ActiveReplicationPair));
}

/*
 * 用例名称: CheckActiveReplicationPairNoActiveIsReport
 * 前置条件：无
 * check点：检查ActiveReplicationPair流程失败
 */
TEST_F(ReplicationCommonServiceTest, CheckActiveReplicationPairNoActiveIsReport)
{
    m_nasReplicationCommonService->m_isBackUpFlow = true;
    stub.set(ADDR(NasReplicationService, ActiveReplicationPair), ActiveReplicationPair_Stub_False);
    stub.set(ADDR(ReplicationCommonService, IsReportAgentErrorCode), IsReportAgentErrorCode_Stub_True);
    EXPECT_EQ(m_nasReplicationCommonService->ActiveReplicationPair(m_localController), MP_FALSE);
    stub.reset(ADDR(NasReplicationService, ActiveReplicationPair));
    stub.reset(ADDR(ReplicationCommonService, IsReportAgentErrorCode));
}

/*
 * 用例名称: CheckActiveReplicationPairNoActiveNoReport
 * 前置条件：无
 * check点：检查ActiveReplicationPair流程失败
 */
TEST_F(ReplicationCommonServiceTest, CheckActiveReplicationPairNoActiveNoReport)
{
    m_nasReplicationCommonService->m_isBackUpFlow = false;
    stub.set(ADDR(NasReplicationService, ActiveReplicationPair), ActiveReplicationPair_Stub_False);
    stub.set(ADDR(ReplicationCommonService, IsReportAgentErrorCode), IsReportAgentErrorCode_Stub_False);
    EXPECT_EQ(m_nasReplicationCommonService->ActiveReplicationPair(m_localController), MP_FALSE);
    stub.reset(ADDR(NasReplicationService, ActiveReplicationPair));
    stub.reset(ADDR(ReplicationCommonService, IsReportAgentErrorCode));
}

/*
 * 用例名称: CheckMonitorExistSnapshotRevert
 * 前置条件：无
 * check点：检查MonitorExistSnapshotRevert流程顺利运行
 */
TEST_F(ReplicationCommonServiceTest, CheckMonitorExistSnapshotRevert)
{
    int64_t errorCode = MP_SUCCESS;
    stub.set(ADDR(BasicJob, IsAbortJob), IsAbortJob_Stub_True);
    EXPECT_EQ(m_nasReplicationCommonService->MonitorExistSnapshotRevert(errorCode), false);
    stub.reset(ADDR(BasicJob, IsAbortJob));
}

/*
 * 用例名称: CheckSwitchOverPrimaryAndSecondResource
 * 前置条件：无
 * check点：检查SwitchOverPrimaryAndSecondResource流程顺利运行
 */
TEST_F(ReplicationCommonServiceTest, CheckSwitchOverPrimaryAndSecondResource)
{
    std::string pairID = "1";
    stub.set(ADDR(NasReplicationService, SplitReplicationPair), SplitReplicationPair_Stub_True);
    stub.set(ADDR(NasReplicationService, SecondaryResourceProtectDisable), SecondaryResourceProtectDisable_Stub_True);
    stub.set(ADDR(ReplicationCommonService, MonitorExistSnapshotRevert), SplitReplicationPair_Stub_True);
    stub.set(ADDR(BasicJob, IsAbortJob), IsAbortJob_Stub_False);
    stub.set(ADDR(NasReplicationService, SwitchOverPrimaryAndSecondResource), SwitchOverPrimaryAndSecondResource_Stub_True);
    stub.set(ADDR(NasReplicationService, SecondaryResourceProtectEnable), SecondaryResourceProtectEnable_Stub_True);
    EXPECT_EQ(m_nasReplicationCommonService->SwitchOverPrimaryAndSecondResource(m_localController, pairID), true);
    stub.reset(ADDR(NasReplicationService, SplitReplicationPair));
    stub.reset(ADDR(NasReplicationService, SecondaryResourceProtectDisable));
    stub.reset(ADDR(ReplicationCommonService, MonitorExistSnapshotRevert));
    stub.reset(ADDR(BasicJob, IsAbortJob));
    stub.reset(ADDR(NasReplicationService, SwitchOverPrimaryAndSecondResource));
    stub.reset(ADDR(NasReplicationService, SecondaryResourceProtectEnable));
}

/*
 * 用例名称: CheckSwitchOverPrimaryAndSecondResourceNoPairID
 * 前置条件：无
 * check点：检查SwitchOverPrimaryAndSecondResource流程因为PairID为空而成功
 */
TEST_F(ReplicationCommonServiceTest, CheckSwitchOverPrimaryAndSecondResourceNoPairID)
{
    std::string pairID = "";
    EXPECT_EQ(m_nasReplicationCommonService->SwitchOverPrimaryAndSecondResource(m_localController, pairID), MP_TRUE);
}

/*
 * 用例名称: CheckSwitchOverPrimaryAndSecondResourceNoSplit
 * 前置条件：无
 * check点：检查SwitchOverPrimaryAndSecondResource流程失败
 */
TEST_F(ReplicationCommonServiceTest, CheckSwitchOverPrimaryAndSecondResourceNoSplit)
{
    std::string pairID = "1";
    stub.set(ADDR(NasReplicationService, SplitReplicationPair), SplitReplicationPair_Stub_False);
    EXPECT_EQ(m_nasReplicationCommonService->SwitchOverPrimaryAndSecondResource(m_localController, pairID), MP_FALSE);
    stub.reset(ADDR(NasReplicationService, SplitReplicationPair));
}

/*
 * 用例名称: CheckSwitchOverPrimaryAndSecondResourceNoDisable
 * 前置条件：无
 * check点：检查SwitchOverPrimaryAndSecondResource流程失败
 */
TEST_F(ReplicationCommonServiceTest, CheckSwitchOverPrimaryAndSecondResourceNoDisable)
{
    std::string pairID = "1";
    stub.set(ADDR(NasReplicationService, SplitReplicationPair), SplitReplicationPair_Stub_False);
    stub.set(ADDR(NasReplicationService, SecondaryResourceProtectDisable), SecondaryResourceProtectDisable_Stub_False);
    EXPECT_EQ(m_nasReplicationCommonService->SwitchOverPrimaryAndSecondResource(m_localController, pairID), MP_FALSE);
    stub.reset(ADDR(NasReplicationService, SplitReplicationPair));
    stub.reset(ADDR(NasReplicationService, SecondaryResourceProtectDisable));
}

/*
 * 用例名称: CheckSwitchOverPrimaryAndSecondResourceNoMonitor
 * 前置条件：无
 * check点：检查SwitchOverPrimaryAndSecondResource流程失败
 */
TEST_F(ReplicationCommonServiceTest, CheckSwitchOverPrimaryAndSecondResourceNoMonitor)
{
    std::string pairID = "1";
    stub.set(ADDR(NasReplicationService, SplitReplicationPair), SplitReplicationPair_Stub_True);
    stub.set(ADDR(NasReplicationService, SecondaryResourceProtectDisable), SecondaryResourceProtectDisable_Stub_True);
    stub.set(ADDR(ReplicationCommonService, MonitorExistSnapshotRevert), SplitReplicationPair_Stub_False);
    stub.set(ADDR(NasReplicationService, SecondaryResourceProtectEnable), SecondaryResourceProtectEnable_Stub_True);
    EXPECT_EQ(m_nasReplicationCommonService->SwitchOverPrimaryAndSecondResource(m_localController, pairID), MP_FALSE);
    stub.reset(ADDR(NasReplicationService, SplitReplicationPair));
    stub.reset(ADDR(NasReplicationService, SecondaryResourceProtectDisable));
    stub.reset(ADDR(ReplicationCommonService, MonitorExistSnapshotRevert));
    stub.reset(ADDR(NasReplicationService, SecondaryResourceProtectEnable));
}

/*
 * 用例名称: CheckSwitchOverPrimaryAndSecondResourceAbortJob
 * 前置条件：无
 * check点：检查SwitchOverPrimaryAndSecondResource流程顺利
 */
TEST_F(ReplicationCommonServiceTest, CheckSwitchOverPrimaryAndSecondResourceAbortJob)
{
    std::string pairID = "1";
    stub.set(ADDR(NasReplicationService, SplitReplicationPair), SplitReplicationPair_Stub_True);
    stub.set(ADDR(NasReplicationService, SecondaryResourceProtectDisable), SecondaryResourceProtectDisable_Stub_True);
    stub.set(ADDR(ReplicationCommonService, MonitorExistSnapshotRevert), SplitReplicationPair_Stub_True);
    stub.set(ADDR(BasicJob, IsAbortJob), IsAbortJob_Stub_True);
    stub.set(ADDR(NasReplicationService, SecondaryResourceProtectEnable), SecondaryResourceProtectEnable_Stub_True);
    EXPECT_EQ(m_nasReplicationCommonService->SwitchOverPrimaryAndSecondResource(m_localController, pairID), false);
    stub.reset(ADDR(NasReplicationService, SplitReplicationPair));
    stub.reset(ADDR(NasReplicationService, SecondaryResourceProtectDisable));
    stub.reset(ADDR(ReplicationCommonService, MonitorExistSnapshotRevert));
    stub.reset(ADDR(BasicJob, IsAbortJob));
    stub.reset(ADDR(NasReplicationService, SecondaryResourceProtectEnable));
}

/*
 * 用例名称: CheckSwitchOverPrimaryAndSecondResourceNoEnable
 * 前置条件：无
 * check点：检查SwitchOverPrimaryAndSecondResource流程失败
 */
TEST_F(ReplicationCommonServiceTest, CheckSwitchOverPrimaryAndSecondResourceNoSwitch)
{
    std::string pairID = "1";
    int64_t errorCode = MP_SUCCESS;
    stub.set(ADDR(NasReplicationService, SplitReplicationPair), SplitReplicationPair_Stub_True);
    stub.set(ADDR(NasReplicationService, SecondaryResourceProtectDisable), SecondaryResourceProtectDisable_Stub_True);
    stub.set(ADDR(ReplicationCommonService, MonitorExistSnapshotRevert), SplitReplicationPair_Stub_True);
    stub.set(ADDR(BasicJob, IsAbortJob), IsAbortJob_Stub_False);
    stub.set(ADDR(NasReplicationService, SwitchOverPrimaryAndSecondResource), SwitchOverPrimaryAndSecondResource_Stub_False);
    stub.set(ADDR(NasReplicationService, SecondaryResourceProtectEnable), SecondaryResourceProtectEnable_Stub_True);
    EXPECT_EQ(m_nasReplicationCommonService->SwitchOverPrimaryAndSecondResource(m_localController, pairID), MP_FALSE);
    stub.reset(ADDR(NasReplicationService, SplitReplicationPair));
    stub.reset(ADDR(NasReplicationService, SecondaryResourceProtectDisable));
    stub.reset(ADDR(ReplicationCommonService, MonitorExistSnapshotRevert));
    stub.reset(ADDR(BasicJob, IsAbortJob));
    stub.reset(ADDR(NasReplicationService, SwitchOverPrimaryAndSecondResource));
    stub.reset(ADDR(NasReplicationService, SecondaryResourceProtectEnable));
}

/*
 * 用例名称: CheckSwitchOverPrimaryAndSecondResourceNoEnable
 * 前置条件：无
 * check点：检查SwitchOverPrimaryAndSecondResource流程失败
 */
TEST_F(ReplicationCommonServiceTest, CheckSwitchOverPrimaryAndSecondResourceNoEnable)
{
    std::string pairID = "1";
    stub.set(ADDR(NasReplicationService, SplitReplicationPair), SplitReplicationPair_Stub_True);
    stub.set(ADDR(NasReplicationService, SecondaryResourceProtectDisable), SecondaryResourceProtectDisable_Stub_True);
    stub.set(ADDR(ReplicationCommonService, MonitorExistSnapshotRevert), SplitReplicationPair_Stub_True);
    stub.set(ADDR(BasicJob, IsAbortJob), IsAbortJob_Stub_False);
    stub.set(ADDR(NasReplicationService, SwitchOverPrimaryAndSecondResource), SwitchOverPrimaryAndSecondResource_Stub_True);
    stub.set(ADDR(NasReplicationService, SecondaryResourceProtectEnable), SecondaryResourceProtectEnable_Stub_False);
    EXPECT_EQ(m_nasReplicationCommonService->SwitchOverPrimaryAndSecondResource(m_localController, pairID), MP_FALSE);
    stub.reset(ADDR(NasReplicationService, SplitReplicationPair));
    stub.reset(ADDR(NasReplicationService, SecondaryResourceProtectDisable));
    stub.reset(ADDR(ReplicationCommonService, MonitorExistSnapshotRevert));
    stub.reset(ADDR(BasicJob, IsAbortJob));
    stub.reset(ADDR(NasReplicationService, SwitchOverPrimaryAndSecondResource));
    stub.reset(ADDR(NasReplicationService, SecondaryResourceProtectEnable));
}

static void GetReplicationSpeed_stub(void* obj, std::shared_ptr<Module::DoradoNas>& deviceController, const std::string& pairID,
    uint64_t& speed)
{
    std::cout << "GetReplicationSpeed_stub get called" << std::endl;
    return;
}

/*
 * 用例名称: CheckCalculateReplicationProgressAndSpeed
 * 前置条件：无
 * check点：检查CalculateReplicationProgressAndSpeed流程不抛异常
 */
TEST_F(ReplicationCommonServiceTest, CheckCalculateReplicationProgressAndSpeed)
{
    uint16_t previousTaskProgress = 20;
    ReplicationPairInfo replicationPairInfo;
    stub.set(ADDR(NasRepServiceObjOp::NasReplicationService, GetReplicationSpeed), GetReplicationSpeed_stub);
    EXPECT_NO_THROW(m_nasReplicationCommonService->CalculateReplicationProgressAndSpeed(m_localController, previousTaskProgress, replicationPairInfo));
    stub.reset(ADDR(NasRepServiceObjOp::NasReplicationService, GetReplicationSpeed));
}

/*
 * 用例名称: CheckRemotePairMachineProc
 * 前置条件：无
 * check点：检查RemotePairMachineProc流程根据状态不同进入不同分支
 */
TEST_F(ReplicationCommonServiceTest, CheckRemotePairMachineProc)
{
    ReplicationPairInfo replicationPairInfo;
    uint16_t retryTimes = 1;

    replicationPairInfo.status = INVALIID;
    EXPECT_EQ(m_nasReplicationCommonService->RemotePairMachineProc(m_localController, m_remoteController, replicationPairInfo, retryTimes), HomoErrorCode::REPLICATION_PAIR_INVAILD_ERROR_CODE);

    replicationPairInfo.status = TO_BE_RECOVERED;
    stub.set(ADDR(NasReplicationService, ActiveReplicationPair), ActiveReplicationPair_Stub_True);
    EXPECT_NO_THROW(m_nasReplicationCommonService->RemotePairMachineProc(m_localController, m_remoteController, replicationPairInfo, retryTimes));
    stub.reset(ADDR(NasReplicationService, ActiveReplicationPair));

    stub.set(ADDR(NasReplicationService, ActiveReplicationPair), ActiveReplicationPair_Stub_False);
    EXPECT_NO_THROW(m_nasReplicationCommonService->RemotePairMachineProc(m_localController, m_remoteController, replicationPairInfo, retryTimes));
    stub.reset(ADDR(NasReplicationService, ActiveReplicationPair));

    replicationPairInfo.status = SPLIT;
    EXPECT_EQ(m_nasReplicationCommonService->RemotePairMachineProc(m_localController, m_remoteController, replicationPairInfo, retryTimes), HomoErrorCode::REPLICATION_PAIR_SPLIT_ERROR_CODE);

    replicationPairInfo.status = NORMAL;
    replicationPairInfo.isPrimary = false;
    EXPECT_EQ(m_nasReplicationCommonService->RemotePairMachineProc(m_localController, m_remoteController, replicationPairInfo, retryTimes), HomoErrorCode::INTERNAL_ERROR_CODE);
}

/*
 * 用例名称: CheckCertVerifyMgr
 * 前置条件：无
 * check点：检查CertVerifyMgr流程顺利运行
 */
TEST_F(ReplicationCommonServiceTest, CheckCertVerifyMgr)
{
    ApplicationEnvironment protectEnv;
    ControlDeviceInfo productDeviceInfo;
    stub.set(ADDR(CertMgr, InitInfo), InitInfo_Stub_True);
    stub.set(ADDR(CertMgr, IsVerify), IsVerify_Stub_True);
    stub.set(ADDR(CertMgr, FlushCertificationToDisk), FlushCertificationToDisk_Stub_True);
    stub.set(ADDR(CertMgr, GetCertPath), GetCertPath_Stub);
    stub.set(ADDR(CertMgr, IncludeRevocationList), IncludeRevocationList_Stub_False);
    EXPECT_EQ(m_nasReplicationCommonService->CertVerifyMgr(protectEnv, productDeviceInfo), MP_TRUE);
    stub.reset(ADDR(CertMgr, InitInfo));
    stub.reset(ADDR(CertMgr, IsVerify));
    stub.reset(ADDR(CertMgr, FlushCertificationToDisk));
    stub.reset(ADDR(CertMgr, GetCertPath));
    stub.reset(ADDR(CertMgr, IncludeRevocationList));
}

/*
 * 用例名称: CheckCertVerifyMgrNoInit
 * 前置条件：无
 * check点：检查CheckUpdateDeviceAvilableIP流程顺利失败
 */
TEST_F(ReplicationCommonServiceTest, CheckCertVerifyMgrNoInit)
{
    ApplicationEnvironment protectEnv;
    ControlDeviceInfo productDeviceInfo;
    stub.set(ADDR(CertMgr, InitInfo), InitInfo_Stub_False);
    EXPECT_EQ(m_nasReplicationCommonService->CertVerifyMgr(protectEnv, productDeviceInfo), MP_FALSE);
    stub.reset(ADDR(CertMgr, InitInfo));
}

/*
 * 用例名称: CheckCertVerifyMgrNoVerify
 * 前置条件：无
 * check点：检查CertVerifyMgr流程顺利运行
 */
TEST_F(ReplicationCommonServiceTest, CheckCertVerifyMgrNoVerify)
{
    ApplicationEnvironment protectEnv;
    ControlDeviceInfo productDeviceInfo;
    stub.set(ADDR(CertMgr, InitInfo), InitInfo_Stub_True);
    stub.set(ADDR(CertMgr, IsVerify), IsVerify_Stub_False);
    EXPECT_EQ(m_nasReplicationCommonService->CertVerifyMgr(protectEnv, productDeviceInfo), MP_TRUE);
    stub.reset(ADDR(CertMgr, InitInfo));
    stub.reset(ADDR(CertMgr, IsVerify));
}

/*
 * 用例名称: CheckCertVerifyMgrNoFlushCertification
 * 前置条件：无
 * check点：检查CertVerifyMgr流程失败
 */
TEST_F(ReplicationCommonServiceTest, CheckCertVerifyMgrNoFlushCertification)
{
    ApplicationEnvironment protectEnv;
    ControlDeviceInfo productDeviceInfo;
    stub.set(ADDR(CertMgr, InitInfo), InitInfo_Stub_True);
    stub.set(ADDR(CertMgr, IsVerify), IsVerify_Stub_True);
    stub.set(ADDR(CertMgr, FlushCertificationToDisk), FlushCertificationToDisk_Stub_False);
    EXPECT_EQ(m_nasReplicationCommonService->CertVerifyMgr(protectEnv, productDeviceInfo), MP_FALSE);
    stub.reset(ADDR(CertMgr, InitInfo));
    stub.reset(ADDR(CertMgr, IsVerify));
    stub.reset(ADDR(CertMgr, FlushCertificationToDisk));
}

/*
 * 用例名称: CheckCertVerifyMgrInclude
 * 前置条件：无
 * check点：检查CertVerifyMgr流程失败
 */
TEST_F(ReplicationCommonServiceTest, CheckCertVerifyMgrInclude)
{
    ApplicationEnvironment protectEnv;
    ControlDeviceInfo productDeviceInfo;
    stub.set(ADDR(CertMgr, InitInfo), InitInfo_Stub_True);
    stub.set(ADDR(CertMgr, IsVerify), IsVerify_Stub_True);
    stub.set(ADDR(CertMgr, FlushCertificationToDisk), FlushCertificationToDisk_Stub_True);
    stub.set(ADDR(CertMgr, GetCertPath), GetCertPath_Stub);
    stub.set(ADDR(CertMgr, IncludeRevocationList), IncludeRevocationList_Stub_True);
    EXPECT_EQ(m_nasReplicationCommonService->CertVerifyMgr(protectEnv, productDeviceInfo), MP_FALSE);
    stub.reset(ADDR(CertMgr, InitInfo));
    stub.reset(ADDR(CertMgr, IsVerify));
    stub.reset(ADDR(CertMgr, FlushCertificationToDisk));
    stub.reset(ADDR(CertMgr, GetCertPath));
    stub.reset(ADDR(CertMgr, IncludeRevocationList));
}

/*
 * 用例名称: CheckCertVerifyMgrNoIncludeFlush
 * 前置条件：无
 * check点：check点：检查CertVerifyMgr流程顺利
 */
TEST_F(ReplicationCommonServiceTest, CheckCertVerifyMgrNoIncludeFlush)
{
    ApplicationEnvironment protectEnv;
    ControlDeviceInfo productDeviceInfo;
    stub.set(ADDR(CertMgr, InitInfo), InitInfo_Stub_True);
    stub.set(ADDR(CertMgr, IsVerify), IsVerify_Stub_True);
    stub.set(ADDR(CertMgr, FlushCertificationToDisk), FlushCertificationToDisk_Stub_True);
    stub.set(ADDR(CertMgr, GetCertPath), GetCertPath_Stub);
    stub.set(ADDR(CertMgr, IncludeRevocationList), IncludeRevocationList_Stub_True);
    stub.set(ADDR(CertMgr, FlushRevocationListToDisk), FlushRevocationListToDisk_Stub_True);
    stub.set(ADDR(CertMgr, GetCrlPath), GetCrlPath_Stub);
    EXPECT_EQ(m_nasReplicationCommonService->CertVerifyMgr(protectEnv, productDeviceInfo), MP_TRUE);
    stub.reset(ADDR(CertMgr, InitInfo));
    stub.reset(ADDR(CertMgr, IsVerify));
    stub.reset(ADDR(CertMgr, FlushCertificationToDisk));
    stub.reset(ADDR(CertMgr, GetCertPath));
    stub.reset(ADDR(CertMgr, IncludeRevocationList));
    stub.reset(ADDR(CertMgr, FlushRevocationListToDisk));
    stub.reset(ADDR(CertMgr, GetCrlPath));
}

/*
 * 用例名称: CheckCertVerifyMgrNoIncludeNoFlush
 * 前置条件：无
 * check点：检查CertVerifyMgr流程失败
 */
TEST_F(ReplicationCommonServiceTest, CheckCertVerifyMgrNoIncludeNoFlush)
{
    ApplicationEnvironment protectEnv;
    ControlDeviceInfo productDeviceInfo;
    stub.set(ADDR(CertMgr, InitInfo), InitInfo_Stub_True);
    stub.set(ADDR(CertMgr, IsVerify), IsVerify_Stub_True);
    stub.set(ADDR(CertMgr, FlushCertificationToDisk), FlushCertificationToDisk_Stub_True);
    stub.set(ADDR(CertMgr, GetCertPath), GetCertPath_Stub);
    stub.set(ADDR(CertMgr, IncludeRevocationList), IncludeRevocationList_Stub_True);
    stub.set(ADDR(CertMgr, FlushRevocationListToDisk), FlushRevocationListToDisk_Stub_False);
    EXPECT_EQ(m_nasReplicationCommonService->CertVerifyMgr(protectEnv, productDeviceInfo), MP_FALSE);
    stub.reset(ADDR(CertMgr, InitInfo));
    stub.reset(ADDR(CertMgr, IsVerify));
    stub.reset(ADDR(CertMgr, FlushCertificationToDisk));
    stub.reset(ADDR(CertMgr, GetCertPath));
    stub.reset(ADDR(CertMgr, IncludeRevocationList));
    stub.reset(ADDR(CertMgr, FlushRevocationListToDisk));
}

/*
 * 用例名称: CheckRemoveCertification
 * 前置条件：无
 * check点：检查RemoveCertification流程顺利运行
 */
TEST_F(ReplicationCommonServiceTest, CheckRemoveCertification)
{
    ApplicationEnvironment protectEnv;
    stub.set(ADDR(CertMgr, InitInfo), InitInfo_Stub_True);
    stub.set(ADDR(CertMgr, IsVerify), IsVerify_Stub_True);
    stub.set(ADDR(CertMgr, RemoveCertAndRevocationListFromDisk), RemoveCertAndRevocationListFromDisk_Stub_True);
    EXPECT_EQ(m_nasReplicationCommonService->RemoveCertification(protectEnv), MP_TRUE);
    stub.reset(ADDR(CertMgr, InitInfo));
    stub.reset(ADDR(CertMgr, IsVerify));
    stub.reset(ADDR(CertMgr, RemoveCertAndRevocationListFromDisk));
}

/*
 * 用例名称: CheckRemoveCertificationNoInit
 * 前置条件：无
 * check点：检查RemoveCertification流程失败
 */
TEST_F(ReplicationCommonServiceTest, CheckRemoveCertificationNoInit)
{
    ApplicationEnvironment protectEnv;
    stub.set(ADDR(CertMgr, InitInfo), InitInfo_Stub_False);
    EXPECT_EQ(m_nasReplicationCommonService->RemoveCertification(protectEnv), MP_FALSE);
    stub.reset(ADDR(CertMgr, InitInfo));
}

/*
 * 用例名称: CheckRemoveCertificationNoVerify
 * 前置条件：无
 * check点：检查RemoveCertification流程顺利运行
 */
TEST_F(ReplicationCommonServiceTest, CheckRemoveCertificationNoVerify)
{
    ApplicationEnvironment protectEnv;
    stub.set(ADDR(CertMgr, InitInfo), InitInfo_Stub_True);
    stub.set(ADDR(CertMgr, IsVerify), IsVerify_Stub_False);
    EXPECT_EQ(m_nasReplicationCommonService->RemoveCertification(protectEnv), MP_TRUE);
    stub.reset(ADDR(CertMgr, InitInfo));
    stub.reset(ADDR(CertMgr, IsVerify));
}

/*
 * 用例名称: CheckRemoveCertificationNoRemove
 * 前置条件：无
 * check点：检查RemoveCertification流程失败
 */
TEST_F(ReplicationCommonServiceTest, CheckRemoveCertificationNoRemove)
{
    ApplicationEnvironment protectEnv;
    stub.set(ADDR(CertMgr, InitInfo), InitInfo_Stub_True);
    stub.set(ADDR(CertMgr, IsVerify), IsVerify_Stub_True);
    stub.set(ADDR(CertMgr, RemoveCertAndRevocationListFromDisk), RemoveCertAndRevocationListFromDisk_Stub_False);
    EXPECT_EQ(m_nasReplicationCommonService->RemoveCertification(protectEnv), MP_FALSE);
    stub.reset(ADDR(CertMgr, InitInfo));
    stub.reset(ADDR(CertMgr, IsVerify));
    stub.reset(ADDR(CertMgr, RemoveCertAndRevocationListFromDisk));
}

/*
 * 用例名称: CheckStartTask
 * 前置条件：无
 * check点：检查StartTask流程顺利
 */
// TEST_F(ReplicationCommonServiceTest, CheckStartTask)
// {
//     typedef bool (*fptr)(ReplicationBackupJob*);
//     fptr ReplicationBackupJob_PreStartTask = (fptr)(&ReplicationBackupJob::PreStartTask);
//     stub.set(ReplicationBackupJob_PreStartTask, PreStartTask_Stub_True);
//     stub.set(ADDR(BasicJob, IsAbortJob), IsAbortJob_Stub_False);
//     stub.set(ADDR(NasReplicationService, OpenPerformanceStatisticSwitch), OpenPerformanceStatisticSwitch_Stub_True);
//     stub.set(ADDR(NasReplicationService, SplitReplicationPair), SplitReplicationPair_Stub_True);
//     stub.set(ADDR(ReplicationCommonService, ActiveReplicationPair), ActiveReplicationPair_Stub_True);
//     EXPECT_EQ(m_nasReplicationCommonService->StartTask(m_localController), MP_TRUE);
//     stub.reset(ReplicationBackupJob_PreStartTask);
//     stub.reset(ADDR(BasicJob, IsAbortJob));
//     stub.reset(ADDR(NasReplicationService, OpenPerformanceStatisticSwitch));
//     stub.reset(ADDR(NasReplicationService, SplitReplicationPair));
//     stub.reset(ADDR(ReplicationCommonService, ActiveReplicationPair));
// }

/*
 * 用例名称: CheckStartTaskNoPreStartTask
 * 前置条件：无
 * check点：检查StartTask流程失败
 */
// TEST_F(ReplicationCommonServiceTest, CheckStartTaskNoPreStartTask)
// {
//     typedef bool (*fptr)(ReplicationBackupJob*);
//     fptr ReplicationBackupJob_PreStartTask = (fptr)(&ReplicationBackupJob::PreStartTask);
//     stub.set(ReplicationBackupJob_PreStartTask, PreStartTask_Stub_False);
//     EXPECT_EQ(m_nasReplicationCommonService->StartTask(m_localController), MP_FALSE);
//     stub.reset(ReplicationBackupJob_PreStartTask);
// }

/*
 * 用例名称: CheckStartTaskAbortJob
 * 前置条件：无
 * check点：检查StartTask流程成功
 */
// TEST_F(ReplicationCommonServiceTest, CheckStartTaskAbortJob)
// {
//     typedef bool (*fptr)(ReplicationBackupJob*);
//     fptr ReplicationBackupJob_PreStartTask = (fptr)(&ReplicationBackupJob::PreStartTask);
//     stub.set(ReplicationBackupJob_PreStartTask, PreStartTask_Stub_True);
//     stub.set(ADDR(BasicJob, IsAbortJob), IsAbortJob_Stub_True);
//     EXPECT_EQ(m_nasReplicationCommonService->StartTask(m_localController), false);
//     stub.reset(ReplicationBackupJob_PreStartTask);
//     stub.reset(ADDR(BasicJob, IsAbortJob));
// }

/*
 * 用例名称: CheckStartTaskNoOpen
 * 前置条件：无
 * check点：检查StartTask流程失败
 */
// TEST_F(ReplicationCommonServiceTest, CheckStartTaskNoOpen)
// {
//     typedef bool (*fptr)(ReplicationBackupJob*);
//     fptr ReplicationBackupJob_PreStartTask = (fptr)(&ReplicationBackupJob::PreStartTask);
//     stub.set(ReplicationBackupJob_PreStartTask, PreStartTask_Stub_True);
//     stub.set(ADDR(BasicJob, IsAbortJob), IsAbortJob_Stub_False);
//     stub.set(ADDR(NasReplicationService, OpenPerformanceStatisticSwitch), OpenPerformanceStatisticSwitch_Stub_False);
//     EXPECT_EQ(m_nasReplicationCommonService->StartTask(m_localController), MP_FALSE);
//     stub.reset(ReplicationBackupJob_PreStartTask);
//     stub.reset(ADDR(BasicJob, IsAbortJob));
//     stub.reset(ADDR(NasReplicationService, OpenPerformanceStatisticSwitch));
// }

/*
 * 用例名称: CheckStartTaskNoPreStartTask
 * 前置条件：无
 * check点：检查StartTask流程失败
 */
// TEST_F(ReplicationCommonServiceTest, CheckStartTaskNoActive)
// {
//     typedef bool (*fptr)(ReplicationBackupJob*);
//     fptr ReplicationBackupJob_PreStartTask = (fptr)(&ReplicationBackupJob::PreStartTask);
//     stub.set(ReplicationBackupJob_PreStartTask, PreStartTask_Stub_True);
//     stub.set(ADDR(BasicJob, IsAbortJob), IsAbortJob_Stub_False);
//     stub.set(ADDR(NasReplicationService, OpenPerformanceStatisticSwitch), OpenPerformanceStatisticSwitch_Stub_True);
//     stub.set(ADDR(NasReplicationService, SplitReplicationPair), SplitReplicationPair_Stub_True);
//     stub.set(ADDR(ReplicationCommonService, ActiveReplicationPair), ActiveReplicationPair_Stub_False);
//     EXPECT_EQ(m_nasReplicationCommonService->StartTask(m_localController), MP_FALSE);
//     stub.reset(ReplicationBackupJob_PreStartTask);
//     stub.reset(ADDR(BasicJob, IsAbortJob));
//     stub.reset(ADDR(NasReplicationService, OpenPerformanceStatisticSwitch));
//     stub.reset(ADDR(NasReplicationService, SplitReplicationPair));
//     stub.reset(ADDR(ReplicationCommonService, ActiveReplicationPair));
// }

static bool CheckAndCreatePair_Stub_True(void *obj)
{
    return true;
}

static bool CheckAndCreatePair_Stub_False(void *obj)
{
    return false;
}

static void GetPairID_Stub_Void(void *obj, std::string &pairID)
{
}

/*
 * 用例名称: CheckAfterInitializeTask
 * 前置条件：无
 * check点：检查AfterInitializeTask流程顺利运行
 */
TEST_F(ReplicationCommonServiceTest, CheckAfterInitializeTask)
{
    stub.set(ADDR(NasReplicationService, GetPairID), GetPairID_Stub_Void);
    typedef bool (*fptr)(ReplicationBackupJob*);
    fptr ReplicationBackupJob_CheckAndCreatePair = (fptr)(&ReplicationBackupJob::CheckAndCreatePair);
    stub.set(ReplicationBackupJob_CheckAndCreatePair, CheckAndCreatePair_Stub_True);
    stub.set(ADDR(NasReplicationService, GetPairInfoByID), GetPairInfoByID_Stub_True);
    stub.set(ADDR(NasReplicationService, SwitchOverPrimaryAndSecondResource), SwitchOverPrimaryAndSecondResource_Stub_True);
    EXPECT_EQ(m_nasReplicationCommonService->AfterInitializeTask(), MP_TRUE);
    stub.reset(ADDR(NasReplicationService, GetPairID));
    stub.reset(ReplicationBackupJob_CheckAndCreatePair);
    stub.reset(ADDR(NasReplicationService, GetPairInfoByID));
    stub.reset(ADDR(NasReplicationService, SwitchOverPrimaryAndSecondResource));
}

/*
 * 用例名称: CheckAfterInitializeTaskNoCreate
 * 前置条件：无
 * check点：检查AfterInitializeTask流程失败
 */
// TEST_F(ReplicationCommonServiceTest, CheckAfterInitializeTaskNoCreate)
// {
//     stub.set(ADDR(NasReplicationService, GetPairID), GetPairID_Stub_Void);
//     typedef bool (*fptr)(ReplicationBackupJob*);
//     fptr ReplicationBackupJob_CheckAndCreatePair = (fptr)(&ReplicationBackupJob::CheckAndCreatePair);
//     stub.set(ReplicationBackupJob_CheckAndCreatePair, CheckAndCreatePair_Stub_False);
//     EXPECT_EQ(m_nasReplicationCommonService->AfterInitializeTask(), MP_FALSE);
//     stub.reset(ADDR(NasReplicationService, GetPairID));
//     stub.reset(ReplicationBackupJob_CheckAndCreatePair);
// }

/*
 * 用例名称: CheckAfterInitializeTask
 * 前置条件：无
 * check点：检查AfterInitializeTask流程顺利运行
 */
// TEST_F(ReplicationCommonServiceTest, CheckAfterInitializeTaskNoGeyPairInfoByID)
// {
//     stub.set(ADDR(NasReplicationService, GetPairID), GetPairID_Stub_Void);
//     typedef bool (*fptr)(ReplicationBackupJob*);
//     fptr ReplicationBackupJob_CheckAndCreatePair = (fptr)(&ReplicationBackupJob::CheckAndCreatePair);
//     stub.set(ReplicationBackupJob_CheckAndCreatePair, CheckAndCreatePair_Stub_True);
//     stub.set(ADDR(NasReplicationService, GetPairInfoByID), GetPairInfoByID_Stub_False);
//     EXPECT_EQ(m_nasReplicationCommonService->AfterInitializeTask(), MP_FALSE);
//     stub.reset(ADDR(NasReplicationService, GetPairID));
//     stub.reset(ReplicationBackupJob_CheckAndCreatePair);
//     stub.reset(ADDR(NasReplicationService, GetPairInfoByID));
// }

/*
 * 用例名称: CheckAfterInitializeTask
 * 前置条件：无
 * check点：检查AfterInitializeTask流程顺利运行
 */
// TEST_F(ReplicationCommonServiceTest, CheckAfterInitializeTaskNoSwitch)
// {
//     stub.set(ADDR(NasReplicationService, GetPairID), GetPairID_Stub_Void);
//     typedef bool (*fptr)(ReplicationBackupJob*);
//     fptr ReplicationBackupJob_CheckAndCreatePair = (fptr)(&ReplicationBackupJob::CheckAndCreatePair);
//     stub.set(ReplicationBackupJob_CheckAndCreatePair, CheckAndCreatePair_Stub_True);
//     stub.set(ADDR(NasReplicationService, GetPairInfoByID), GetPairInfoByID_Stub_True);
//     stub.set(ADDR(NasReplicationService, SwitchOverPrimaryAndSecondResource), SwitchOverPrimaryAndSecondResource_Stub_False);
//     EXPECT_EQ(m_nasReplicationCommonService->AfterInitializeTask(), MP_TRUE);
//     stub.reset(ADDR(NasReplicationService, GetPairID));
//     stub.reset(ReplicationBackupJob_CheckAndCreatePair);
//     stub.reset(ADDR(NasReplicationService, GetPairInfoByID));
//     stub.reset(ADDR(NasReplicationService, SwitchOverPrimaryAndSecondResource));
// }

static bool QueryResourceMock(
    const std::string key, AppProtect::ResourceStatus &ret, const std::string &mainJobId, const std::string &subJobId)
{
    AppProtect::Resource resource;
    resource.__set_resourceValue("1");
    ret.resource = resource;
    return true;
}

/*
 * 用例名称: CheckSetDataForJobDetail
 * 前置条件：无
 * check点：检查SetDataForJobDetail流程无异常
 */
TEST_F(ReplicationCommonServiceTest, CheckSetDataForJobDetail)
{
    SubJobDetails subJobDetails;
    m_nasReplicationCommonService->m_isReportData = true;
    m_nasReplicationCommonService->m_usedCapacity = 1;
    stub.set((int(DoradoNas::*)(std::string, DeviceDetails&))ADDR(DoradoNas, QueryFileSystem), QueryFileSystem_Stub_True);
    stub.set(ADDR(HetroCommonService, QueryResource), QueryResourceMock);
    EXPECT_NO_THROW(m_nasReplicationCommonService->SetDataSizeForJobDetail(subJobDetails));
    stub.reset(ADDR(HetroCommonService, QueryResource));
    stub.reset((int(DoradoNas::*)(std::string, DeviceDetails&))ADDR(DoradoNas, QueryFileSystem));
}

/*
 * 用例名称: CheckSetDataForJobDetailFail
 * 前置条件：无
 * check点：检查SetDataForJobDetail流程无异常
 */
TEST_F(ReplicationCommonServiceTest, CheckSetDataForJobDetailFail)
{
    SubJobDetails subJobDetails;
    m_nasReplicationCommonService->m_isReportData = false;
    m_nasReplicationCommonService->m_usedCapacity = 1;
    stub.set((int(DoradoNas::*)(std::string, DeviceDetails&))ADDR(DoradoNas, QueryFileSystem), QueryFileSystem_Stub_False);
    stub.set(ADDR(HetroCommonService, QueryResource), QueryResourceMock);
    EXPECT_NO_THROW(m_nasReplicationCommonService->SetDataSizeForJobDetail(subJobDetails));
    stub.reset(ADDR(HetroCommonService, QueryResource));
    stub.reset((int(DoradoNas::*)(std::string, DeviceDetails&))ADDR(DoradoNas, QueryFileSystem));
}